package utils

import "sync"

type SyncArrayList struct {
	rw  *sync.RWMutex
	lst *ArrayList
}

func NewSyncArrayList(cap int) *SyncArrayList {
	rval := &SyncArrayList{
		lst: NewArrayList(cap),
		rw:  new(sync.RWMutex),
	}
	return rval
}

func (this *SyncArrayList) Push(val interface{}) {
	this.rw.Lock()
	defer this.rw.Unlock()
	this.lst.Append(val)
}

func (this *SyncArrayList) Count() int {
	this.rw.Lock()
	defer this.rw.Unlock()
	return this.lst.Count()
}

func (this *SyncArrayList) PushList(lst ...interface{}) {
	this.rw.Lock()
	defer this.rw.Unlock()
	this.lst.AppendList(lst...)
}

func (this *SyncArrayList) PopHead() (ok bool, val interface{}) {
	this.rw.Lock()
	defer this.rw.Unlock()
	return this.lst.PopHead()
}

func (this *SyncArrayList) PopHeadAndRange(max int, fn func(val interface{}) bool) {
	this.rw.Lock()
	lst := this.lst.PopHeadMax(max)
	this.rw.Unlock()
	for i := 0; i < len(lst); i++ {
		if !fn(lst[i]) {
			break
		}
	}
}
